home *** CD-ROM | disk | FTP | other *** search
- TUTORIAL FOR IDCRACKME v.5.0 by The_Dux
- =======================================
-
- INTRO:
- A little intro before we start.
- This is a very very long tutorial so be patient...
- The length of this is strictly realted with the type of crackme that
- TORN@DO wrote.
- I'm not a native english person so... forgive my mistakes. Thanks.
-
- TUT:
- Let's start.
- As usual we fire up the program and see around to find some button
- like 'Register', etc.
- We didn't found anything except two buttons: one enabled (the About)
- and one disabled (the Request).
- So we can't insert our data directly to the program. We must
- reconstruct the registration file manually.
- Ok, as wrote in the Readme file this is a packed file so we can't
- disassemble it. Well...
- Now we have to choose:
- a) We can debug it directly with SoftIce or similar
- b) We can unpack it manually and try deadlisting
-
- I prefer the first one so i've tried with SoftIce.
- The first problem that we encounter is that the decription routine is
- very long and we can only 'step into' to go on otherwise we exit from
- SoftIce and the program load itself without us...
- So we can try two things:
- a) We can set a breakpoint to OpenFile, CreateFile, CreateFileEx,
- ReadFile and ReadFileEx to intercept the reading or
- b) We can try another approach that is more nice and 'aristocratic'
-
- We try the second one, of course, because we are not novice and we
- crack with a little of brain, right?
- So, let's take a look at the main window of the program.
- We have a dialog, or a window, we don't say, with four main object:
- two pictures and two buttons.
- The pictures show some nice text but the button are one enabled and
- one disabled. This is very important and from here we can start
- reconstruct the missing key file. How? Be patient...
-
- We all know that a button is enabled by a call to the EnableWindow
- function. Reading our Win32 API references we see that the function
- take two parameters: hWnd & bEnable.
- The first one is the handle to the window (or the button, btw) that
- receive our boolean value (enabled or disabled, 0 or 1) represented
- by bEnable.
- Let's think a bit...
- We can't enable the button from the window nor from the about box
- so the button is enabled ONLY when we reconstruct the key file...
-
- Now that we reverse with word this we set a breakpoint on execution
- (bpx in SoftIce) at EnableWindow. Launch the program and... voilα
- SoftIce pop up and put ourseleves in the middle of our beloved
- function...
- Think a little again: we have two button so how much call to
- EnableWindow? Two!!
- Exit SoftIce with CTRL+D and we reenter immediately in SoftIce.
- Ok now F11 once to exit from EnableWindow and we fall into the
- crackme's code. Well.
- Move around the code and see the GetDlgItem function that retrieve
- the handle of control (our button). We also see, some lines above,
- a PUSH 00 that is like PUSH FALSE or PUSH DISABLED.
- Yes! We found where the routine where button is disabled!
- Now move the cursor above to see a conditional jump but there are
- only some pushes... like the beginning of a call. In fact this is
- a little call that ends some lines below the Call EnableWindow
- with a RET.
- Trace till there and see where we return. The lines that we see
- are few and many INT 3 are there...
- Let's take a look at the lines above and we see another RET
- instruction, after another call...
- Well our experience say us that this is the place where the key
- file is verified and then something decide how we are (good or
- bad crackers...).
- So write down the addres after the first occurrence that is in
- my machine 401D18.
- Go up to find some conditional jump that refer to this location
- and with a lot of surprise we find not one but many conditional
- jump of this type.
- Watching the lines above each jump we notice that we have allways
- a call, a stack adjustment, and a test that verify the value of
- eax that must be zero or non zero.
- Ok, now we have founded the reference to the EnableWindow that
- disable the button.
- Set a breakpoint to the first call (401BEC) and step into to see
- what happen.
- Ok, now we have to trace well the first part of this call cause
- as we can see we found this initial lines in each call that
- follow and that return the magic value in eax that decide if we
- are good or not so good.
-
- Here is the code taken from W32Dasm:
- (Forget the addresses, they are false beacause this is a dump of
- memory from SoftIce)
-
- :00000000 83EC30 sub esp, 00000030
- :00000003 33D2 xor edx, edx
- :00000005 33C0 xor eax, eax
- :00000007 B907000000 mov ecx, 00000007
- :0000000C 88542410 mov byte ptr [esp+10], dl
- :00000010 57 push edi
- :00000011 8D7C2415 lea edi, dword ptr [esp+15]
- :00000015 F3 repz
- :00000016 AB stosd
- :00000017 AA stosb
- :00000018 8D442405 lea eax, dword ptr [esp+05]
- :0000001C 88542404 mov byte ptr [esp+04], dl
- :00000020 8910 mov dword ptr [eax], edx
- :00000022 895004 mov dword ptr [eax+04], edx
- :00000025 895008 mov dword ptr [eax+08], edx
- :00000028 6689500C mov word ptr [eax+0C], dx
- :0000002C B801000000 mov eax, 00000001
- :00000031 8A8857D04000 mov cl, byte ptr [eax+0040D057]
- :00000037 40 inc eax
- :00000038 80F133 xor cl, 33
- :0000003B 83F810 cmp eax, 00000010
- :0000003E 884C0412 mov byte ptr [esp+eax+12], cl
- :00000042 76ED jbe 00000031
- :00000044 8D442414 lea eax, dword ptr [esp+14]
- :00000048 8D4C2404 lea ecx, dword ptr [esp+04]
- :0000004C 50 push eax
- :0000004D 6828D74000 push 0040D728
- :00000052 51 push ecx
- :00000053 E858360000 call 000036B0
- :00000058 8D4C2410 lea ecx, dword ptr [esp+10]
- :0000005C 83C40C add esp, 0000000C
- :0000005F 6824D74000 push 0040D724
- :00000064 51 push ecx
- :00000065 E826360000 call 00003690
- :0000006A 83C408 add esp, 00000008
- :0000006D 85C0 test eax, eax
- :0000006F 7413 je 00000084
- :00000071 50 push eax
- :00000072 E829340000 call 000034A0
- :00000077 83C404 add esp, 00000004
- :0000007A B801000000 mov eax, 00000001
- :0000007F 5F pop edi
- :00000080 83C430 add esp, 00000030
- :00000083 C3 ret
-
- :00000084 33C0 xor eax, eax
- :00000086 5F pop edi
- :00000087 83C430 add esp, 00000030
- :0000008A C3 ret
-
- Ok, it's all the call but we can slowly learn it's structure.
- Let's start. Where? From the beginning of course...
- At the address 0 (is a fake address, remember) we adjust the stack
- and we set some values (not so important) till 2Ch.
- Here we set eax to 1 and enter in a loop, repeated 16 times, in wich
- we get a value from somewhere, we xor it with 33h, and we put the
- xored value in a buffer.
- This loop as i said xor an array of data and put the result in
- another array.
- For educational purpose here are the crypted and the decrypted
- arrays:
-
- Crypted : avtz`gargz|} (and another char that is 1Dh(can't represent))
- Decrypted: REGISTRATION.DAT
-
- As you see we decrypt the buffer to get the real name of the key file.
- So create it! (of course in the same directory)
- Ok, now back on our code. We know that eax must be non-zero to
- fake the jz jump just after our breakpoint.
- We see two RET and after each one eax is filled with different
- values: 1 for the first RET (at 7Ah) and 0 for the second RET (84h).
- The only way to go to 84h is with the jump at 6Fh that verify the
- return value of the above call. We can go through this call and so
- on and so on... or we can simply guess what this call do.
- Really I don't know what this call do but i believe that return
- the handle of file (with a call to OpenFile maybe) and if eax is
- zero (that is the error code of OpenFile for failed operation) it
- jump and return a zero that say we are bad crackers.
- So try it! It's as I said... No matter how the check is done
- (not because we are lamers but because we can't trace through these
- calls or our key file never watch the sun light!!).
- We have reversed almost 50% of the protection, I think, because
- all the others calls begin as this.
- Ok now we come back and set another breakpoint to the next call
- (that now is executed because we have the REGISTRATION.DAT).
-
- Well, well, we are still in the night because we have just created
- the file... NO!
- Now we go to the next call and see some operations (at the end)
- that substract 400h (1024d) to a value stored in ebx. Now that we
- are here we can choose:
- a) trace the call to find where value ebx is computed
- b) think a little as TORN@DO and guess what's this
-
- We try... b!
- Ok, now the program know that the key file exist what more?
- We can check many things but one is the more probable (watching
- that 400h or 1024d also): the length of our file.
- Yes, is as said and the length must be 1024 bytes.
- Try yourself if you don't believe me. I don't have time (and
- space) to explain those little particulars.
- so we return with the correct value in eax and set a breakpoint
- on next call.
-
- Go inside, jump the known part, and pay attention to what happens
- here is that movsx, mov and cmp loop. With the call above we read
- the entire file (important: the entire file) and we put it onto
- a buffer pointed by the stack (esp). After little tricks i've founded
- that the file is stored starting from address [esp+3C].
- I've simply putted a 01h byte at the beginning and at the end of our
- key file and searched for it near the pointer to [esp+eax+38] readed
- onto the code.
- This call is the most important part of key file because here we can
- reconstruct our key file with our name...
- I have to say that our name is crippled with a simple algorithm that
- xor every char of our name with the length of name.
- As we see after some other calls depending on the name we change a
- handful of byte, but later...
- So insert our name (crippled of course!!).
- This time i've crippled a name, Scully, that is the name I usually
- use to find the serial number.
- So we can write at the offset 99 of the key-file the crippled name.
- A little things: the 99 is computed as I said above basing on the
- beginning of file situated at [esp+3C] and the lines that move our
- name to a buffer. I can't explain i've said but it isn't so hard.
-
- My cryppled name is Uesjj (plus the 7Fh char that i can't represent).
-
- The only limit to the name is the length: it must be greater than 3
- and lesser than 55 chars.
-
- Now we go further and set a breakpoint on next call.
- The address is 401E90 and I have to say that the last known call
- (the one that is repeated every call) read from file and place
- start the buffer at esp+38.
- In this call we do a simply check to verify the header of the key
- file that is 9 bytes long.
-
- The header is already stored in the exe (decrypted of course!) and
- is compared with a routine of three line.
- If you don't find it by yourself here is what it is:
- 06h 0Ah 15h 07h 13h 10h 0Ah 72h 0Ch
-
- As you can see it's a sequence of nine byte.
-
- We are done with this call too so set a breakpoint on the next.
- This call is another check to verify the integrity of our key file.
- We have 7 bytes that are readed from the buffer (that is always
- where we put the content of the registration file), xored with some
- values and then compared with other values.
- To simplify the tedious job here are the bytes to put at offset 0Ah:
- 07h 20h 34h 3Eh 09h 07h 0Ah
-
- Note: The first 07h is taken from the last reading operation of the
- call. THEY AREN'T IN SEQUENCE AS IN REG FILE.
-
- Ok, next call and set the new breakpoint.
- In this call we get some other bytes (4) just after the 0Ah of the
- above call.
- The byte are compare directly with cmp or tested if they must be zero.
- Here are they (to put after the last 0Ah, offset 11h):
- 08 00 00 05
-
- Now we are ready to set the next breakpoint.
- In this call what we have? The same things as in the above one...
- We have some value that must be equal to our values xor dummy val.
- So here are they: (they are 17 starting from offset 15h)
- 08 05 00 12h 0Ah 12h 03 12h 02 2Ch 43h 08 02 2Ah 0Ah 44h 54h
-
- And now what we do? We set a breakpoint on next call...
- This call is a bit obscure but we resolve it in a while. With this
- call the crackme check a date stored in the key file with the
- current date. The key file date must be greater or equal to the
- current one.
- We simply store a 07CFh word in our file at the offset 52h and we
- pass this check.
- Now we have to look at another value that here appear as unused but
- in the last call we find some references to this. We can modify it if
- we want but, you are warned, we have to do more complex math later so
- believe me, leave 0 this byte that is at the offset 50h.
-
- Well... slowly but calm we are here...what more? some more calls...
- we are about in the middle of the check routine so we must take a
- rest here...
-
- Good rest? well... let's start again with the famous breakpoint on
- next call.
- At the beginning of this tute we see the crackme like a heavy slope,
- now we are in a descent...
- This call tell us nothing... It simply compares two byte of our code
- and verify that they are lesser than two values. Ok leave these byte
- null (0 - at offset 55h & 56h) and go on with next call.
-
- Set The Breakpoint.
- Now a call that will relax ourself and free our mind...
- We trace till we reach the usual set of known code and then we see a
- routine, repeated 88 times that compare some value with some other
- situated at offset 0D0h of our key file.
-
- What are these bytes? They are a joke...
- Here are they: (all uppercase)
-
- SUPPORT THE SOFTWARE AUTHORS BY BUYING THE PROGRAMS IF YOU USE THEM
- AFTER CRACKING THEM!
-
- Nice isn't it?
- Write this words on the file starting from 0D0h and go on.
-
- Set The Breakpoint.
- In this call, with a little different routine to the above one we
- do the same thing: we compare another handful of bytes.
- They are (starting from offset 150h):
-
- 6;9>>2TJR255<5>=92:8><=
-
- Set The Breakpoint.
- Now begin the part that is a little harder than the previous one.
- We start generating checksum...
- Ok, don't be demoralized, it's only math...
- Well, we begin with a little look around the code:
- We see a loop repeated 100 times and a division by 0Ah
- Now I try explain you what happen:
- Here we compute a checksum (only a sum) of the first 100 bytes.
- After this we xor it with 7CFh (1999, nice!) and we divide by 0Ah.
- The result of division must be equal to a byte stored in the key file
- at the offset 3B0h.
- We have to do all this maths? Nope, the computer do it for us...
- We only wait at the line with cmp ecx, eax and write down what we
- have in eax (the byte of checksum just computed).
- Now we open the key file and we write this byte to the 3B0h offset.
- Done.
- Note: in this call we have a handful of value taken here and there
- from the key file. Believe me, leave it to zero...
-
- Set The Breakpoint.
- Another call very similar to the above one.
- We find some more maths... leave the computer alone to do that
- (hey, it's it job and it do it very quickly...). We wait at the
- usual cmp reg32, reg32 and write down the addresses.
- What more? NOTHING.
- The call that follow do the same job and we have to wait at the
- cmp reg32, reg32 instruction to find the correct values...
-
- Another things: the last call verify that the last byte of the key
- file is 52h. Don't miss it!
-
- FINAL NOTES:
- We have successfully rebuild the missing key file... what more?
- A key-gen... Wait, it's a bit longer...
- For those of you that wasn't able to follow me here is the dump of
- my REGISTRATION.DAT (Pay attention: don't modify any byte because
- the final checksum may change!):
-
- Taken from HexWorkshop v.2.54
- 00000000 060A 1507 1310 0A72 0C00 0720 343E 0907 .......r... 4>..
- 00000010 0A08 0000 0508 0500 120A 1203 1202 2C43 ..............,C
- 00000020 0802 2A0A 4454 2101 5269 3A00 0000 0000 ..*.DT!.Ri:.....
- 00000030 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 00000040 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 00000050 0000 07CF 0000 0000 0000 0000 0000 0000 ................
- 00000060 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 00000070 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 00000080 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 00000090 0000 0000 0000 0000 0055 6573 6A6A 7F00 .........Uesjj..
- 000000A0 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 000000B0 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 000000C0 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 000000D0 5355 5050 4F52 5420 5448 4520 534F 4654 SUPPORT THE SOFT
- 000000E0 5741 5245 2041 5554 484F 5253 2042 5920 WARE AUTHORS BY
- 000000F0 4255 5949 4E47 2054 4845 2050 524F 4752 BUYING THE PROGR
- 00000100 414D 5320 4946 2059 4F55 2055 5345 2054 AMS IF YOU USE T
- 00000110 4845 4D20 4146 5445 5220 4352 4143 4B49 HEM AFTER CRACKI
- 00000120 4E47 2054 4845 4D21 0000 0000 0000 0000 NG THEM!........
- 00000130 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 00000140 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 00000150 363B 393E 3E32 544A 5232 3535 3C35 3E3D 6;9>>2TJR255<5>=
- 00000160 3932 3A38 3E3C 3D00 0000 0000 0000 0000 92:8><=.........
- 00000170 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 00000180 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 00000190 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 000001A0 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 000001B0 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 000001C0 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 000001D0 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 000001E0 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 000001F0 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 00000200 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 00000210 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 00000220 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 00000230 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 00000240 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 00000250 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 00000260 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 00000270 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 00000280 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 00000290 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 000002A0 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 000002B0 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 000002C0 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 000002D0 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 000002E0 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 000002F0 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 00000300 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 00000310 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 00000320 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 00000330 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 00000340 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 00000350 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 00000360 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 00000370 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 00000380 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 00000390 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 000003A0 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 000003B0 6272 0400 120F 0000 0000 0000 0000 0000 br..............
- 000003C0 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 000003D0 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 000003E0 0000 0000 0000 0000 0000 0000 0000 0000 ................
- 000003F0 0000 0000 0000 0000 0000 0000 0000 0052 ...............R
-
- Ok, I have finished my very very long tutorial.
- In the words above I don't say a little things:
- the objective. Mine is... I can't tell you. If you follow my
- tutorial step by step and call by call you see a little nice
- joke from TORN@DO with the main icon. Really cool!
-
- The_Dux, 12 July 1999.